module Globals
    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Parameters and Grids
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    ! Preference parameters
    real(8), parameter :: sg     = 2.0D0                        ! utility consumption curvature
    real(8), parameter :: varphi = 2.5D0                        ! utility labor curvature
    
    ! Production parameters
    real(8), parameter :: alpha  = 0.64D0                       ! labor exponent in production function 
    real(8), parameter :: delta  = 0.06D0                       ! depreciation rate
    
    ! Computational parameters
    real(8), parameter :: tiny   = 1D-13                        ! lower bound for consumption
    real(8) :: ymean, ymean_new                                 ! mean income

    ! Calibrated parameters
    real(8) :: B                                                ! labor disutility
    real(8) :: G                                                ! government spending
    real(8) :: Debt                                             ! government debt
    real(8) :: ymeanCalib                                       ! mean income in calibration
    real(8) :: beta                                             ! discount factor
    
    ! Prices
    real(8) :: wge                                              ! wage
    real(8) :: r, r_new                                         ! interest rate
    
    ! Aggregate variables
    real(8) :: Yagg, Kagg, Lagg, Hagg, Tagg, Cagg                  ! output, capital, aggregate efficiency units of labor, average (unweighted) labor supply, transfer
    
    ! Capital tax
    real(8), parameter :: tauk = 0.298366d0                     ! capital tax rate
    real(8), parameter :: tauC = 0.06263d0                      ! capital tax rate

    ! Tax and transfer function
    real(8) :: lambda                                           ! tax function parameter -> level
    real(8) :: gamma                                            ! tax function parameter -> progressivity
    real(8) :: mt, rt, omegat                                   ! targeted transfer
    integer :: norm_version                                     ! indicator for choice of normalization: 1) mean income; 2) median income; 3) mean income of the third quintile

    ! Grids
    integer, parameter :: Nx = 19                               ! number of grid points for idiosyncratic productivity
    real(8) :: x_vec(Nx)                                        ! idiosyncratic productivity grid
    integer, parameter :: Na = 300                              ! number of grid points for assets
    integer, parameter :: Nh = 41                               ! number of grid points for labor supply
    real(8) :: a_vec(Na), h_vec(Nh)                             ! grids for assets and labor supply
    real(8)            :: Px(Nx,Nx)                             ! transition matrix for idiosyncratic productivity
    real(8), parameter :: amin = -0.22D0, amax = 110.0D0          ! bounds for asset grid
    real(8), parameter :: hmin = 0.000001D0, hmax = 1.0D0       ! bounds for labor supply grid
    real(8), parameter :: aprm = 0.35d0                         ! spacing of asset grid

    ! State space
    integer, parameter                 :: dim = 2               ! # of state variables
    integer, parameter                 :: NS = Na*Nx            ! combined number of idiosyncratic states
    real(8) :: S(NS,dim)                                        ! Vectorized states (dim 1: assets; dim 2: idiosyncratic productivity)
    integer :: xind(NS), aind(NS)                               ! index of endowment in the state S(is,1) = y_vec(yind(is))
    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Steady state
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    ! Value function and policies    
    real(8) :: V(NS), Ve(NS)                                    ! value functions
    real(8) :: a_pol(NS), c_pol(NS), h_pol(NS)                  ! policy functions
    real(8) :: mu(NS)                                           ! stationary measure
    real(8) :: errV                                             ! error in VFI
    
    ! Counter, tolerance levels
    real(8) :: errmu                                            ! error measure
    integer :: maxit_r                                          ! maximum number of iterations to clear asset markets
    integer :: maxitV                                           ! maximum number of iterations for VFI
    real(8) :: ww                                               ! updating speed of VFI
    real*8  :: tol_lda, tolmu, tolV, tol_r                      ! tolerance level
    real(8) :: error_vec(4)                                     ! error vector to store errors in asset mkt. clearing, govt. budget, measure, VFI
    
    ! Newton, tolerance and errors
    real(8) :: tolf                                             ! tolerance level
    real(8) :: asset                                            ! error asset market clearing
    real(8) :: BC                                               ! error govt budget clearing
    integer :: maxitQbs, maxitQ, max_exit                       ! max iteration variables

    ! Newton, matrices
    integer, parameter :: NQ = 2                                ! lambda,r
    real(8), dimension(NQ,NQ) :: JACmat                         ! Jacobian
    real(8), dimension(NQ) :: x0, ED0, EDx                      ! excess demand

    ! Initial steady-state
    real(8) :: lambda_init, mt_init, r_init                     ! initial eqm prices and taxes
    real(8) :: error_vec_init(4)                                ! error vector to store errors in asset mkt. clearing, govt. budget, measure, VFI
    real(8), dimension(NS) :: a_pol_init, c_pol_init, h_pol_init! initial policy functions
    real(8), dimension(NS) :: mu_init, V_init                   ! initial measure
    real(8) :: Kagg_init                                        ! initial capital stock

    ! Long-run steady-state
    real(8) :: lambda_lr, r_lr, mt_lr                           ! final eqm prices and taxes
    real(8) :: error_vec_lr(4)                                  ! error vector to store errors in asset mkt. clearing, govt. budget, measure, VFI
    real(8), dimension(NS) :: a_pol_lr, c_pol_lr, h_pol_lr      ! final policy functions
    real(8), dimension(NS) :: mu_lr, V_lr                       ! final measure and value function
    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! Transition
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    ! Transition length
    integer, parameter :: T_TR = 120                            ! number of periods in transition

    ! Bounds for equilibrium variables along transition
    real(8), parameter :: lbdlb = 0.05D0, lbdub = 3D0           ! bounds for tax level
    real(8), parameter :: mtlb = -0.05D0, mtub = 3D0            ! bounds for transfer level
    real(8), parameter :: rlb = 0.001d0, rub = 2D0              ! bounds for interest rate
    real(8) :: albd, xlbd, amt, xmt, ar, xr                     ! variables to transform bounds

    real(8) :: Yagg_TR(T_TR), Kagg_TR(T_TR), Lagg_TR(T_TR), Cagg_TR(T_TR)       ! aggregates along the transition
    real(8) :: r_TR(T_TR), r_new_TR(T_TR), lambda_TR(T_TR), mt_TR(T_TR), wge_TR(T_TR)   ! prices and tax parameters along the transition
    real(8) :: BC_TR(T_TR), asset_TR(T_TR)                      ! errors in govt budget and asset market clearing along transition

    ! Value Function and Policies
    real(8), dimension(NS,T_TR)   :: V_TR, Ve_TR, mu_TR                         ! value functions
    real(8), dimension(NS,T_TR)   :: a_pol_TR, c_pol_TR, h_pol_TR               ! policy functions

    integer, parameter :: Kuvar = 2*T_TR                                        ! # of unknowns to solve for
    real(8)            :: ED_ss(Kuvar), ED_t(Kuvar), JACmat_t(Kuvar,Kuvar)      ! excess demand, Jacobian
    
    integer :: index_it, index_exit
    
    ! Needed for elasticities
    real(8) :: epsilon
    real(8), dimension(NS,2) :: h_pol_epsilon, marginal_rate, ytot_epsilon, yl_epsilon
    integer :: index_epsilon
    
end module Globals

